#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
#include <time.h>
#include <string.h>
#include "logic/ghost.h"
#include "data/map.h"
#include "logic/pacman.h"
#include "logic/leaderboardlogic.h"
#include "ui/leaderboardui.h"
#include "logic/skilltree.h"
#include "ui/skilltreeui.h"

#define GHOST_COUNT 4

// 游戏状态
typedef enum {
    GAME_RUNNING,
    GAME_WIN,
    GAME_OVER
} GameState;

// 游戏结构体
typedef struct {
    Map map;
    Pacman pacman;
    Ghost ghosts[GHOST_COUNT];
    GameState state;
} Game;

char playerName[NAME_LEN]; // 全局变量，方便各处使用

// 控制台缓冲区句柄
HANDLE hConsole;
HANDLE hNewScreenBuffer;
COORD coordScreen = {0, 0};
CONSOLE_SCREEN_BUFFER_INFO csbi;
DWORD dwConSize;
DWORD dwNumWritten;

// Windows控制台设置
void setup_console() {
    // 获取标准输出句柄
    hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    
    // 创建新的屏幕缓冲区
    hNewScreenBuffer = CreateConsoleScreenBuffer(
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        CONSOLE_TEXTMODE_BUFFER,
        NULL
    );
    
    // 获取屏幕缓冲区信息
    GetConsoleScreenBufferInfo(hConsole, &csbi);
    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
    
    // 设置控制台标题
    SetConsoleTitle("Pacman Game");
    
    // 设置控制台字体
    CONSOLE_FONT_INFOEX fontInfo;
    fontInfo.cbSize = sizeof(fontInfo);
    GetCurrentConsoleFontEx(hConsole, FALSE, &fontInfo);
    wcscpy(fontInfo.FaceName, L"Consolas");
    fontInfo.dwFontSize.Y = 16;
    SetCurrentConsoleFontEx(hConsole, FALSE, &fontInfo);
    
    // 隐藏光标
    CONSOLE_CURSOR_INFO cursorInfo;
    cursorInfo.dwSize = 1;
    cursorInfo.bVisible = FALSE;
    SetConsoleCursorInfo(hConsole, &cursorInfo);
    SetConsoleCursorInfo(hNewScreenBuffer, &cursorInfo);
}

// 清理控制台资源
void cleanup_console() {
    CloseHandle(hNewScreenBuffer);
}

// 清屏函数
void clear_screen() {
    DWORD written;
    COORD topLeft = {0, 0};
    
    // 填充空格以清屏
    FillConsoleOutputCharacter(hConsole, ' ', dwConSize, topLeft, &written);
    FillConsoleOutputAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
                             dwConSize, topLeft, &written);
    
    // 将光标移动到开始位置
    SetConsoleCursorPosition(hConsole, topLeft);
}

// 检查是否有输入
int kbhit() {
    return _kbhit();
}

// 初始化游戏
void game_init(Game* game) {
    // 初始化地图
    map_init(&game->map);
    
    // 初始化Pacman
    pacman_init(&game->pacman, 10, 10);
    
    // 初始化幽灵在开阔地带
    ghost_init(&game->ghosts[0], 1, 2);
    ghost_init(&game->ghosts[1], 1, 3);
    ghost_init(&game->ghosts[2], 1, 4);
    ghost_init(&game->ghosts[3], 1, 5);
    
    game->state = GAME_RUNNING;
}

// 清空地图上的所有G
void clear_ghosts(Map* map) {
    for (int i = 0; i < MAP_ROWS; i++) {
        for (int j = 0; j < MAP_COLS; j++) {
            if (map->grid[i][j] == GHOST) {
                map->grid[i][j] = EMPTY;
            }
        }
    }
}

// 处理输入
Direction handle_input() {
    if (kbhit()) {
        char key = _getch();
        switch (key) {
            case 'w':
            case 'W':
                return DIR_UP;
            case 's':
            case 'S':
                return DIR_DOWN;
            case 'a':
            case 'A':
                return DIR_LEFT;
            case 'd':
            case 'D':
                return DIR_RIGHT;
            case 27: // ESC
                exit(0);
        }
    }
    return -1; // 无输入
}

// 更新游戏状态
void game_update(Game* game) {
    // 处理Pacman移动
    Direction dir = handle_input();
    if (dir != -1) {
        pacman_move(&game->pacman, &game->map, dir);
    }
    
    // 更新幽灵位置
    for (int i = 0; i < GHOST_COUNT; i++) {
        ghost_move(&game->ghosts[i], &game->map, &game->pacman);
        
        // 检查碰撞
        if (ghost_collision(&game->ghosts[i], &game->pacman)) {
            game->pacman.lives--;
            if (!pacman_is_alive(&game->pacman)) {
                game->state = GAME_OVER;
            }
        }
    }
    
    // 检查胜利条件
    if (game->map.dotCount == 0) {
        game->state = GAME_WIN;
    }
}

// 绘制游戏
void game_draw(Game* game) {
    clear_screen();

    // 每帧绘制前清空所有G，避免残影
    clear_ghosts(&game->map);

    // 每帧都绘制Pacman和所有幽灵
    pacman_draw(&game->pacman, &game->map);
    for (int i = 0; i < GHOST_COUNT; i++) {
        ghost_draw(&game->ghosts[i], &game->map);
    }

    // 绘制地图
    map_draw(&game->map);

    // 显示分数和生命值
    printf("\nName: %s  Score: %d  Lives: %d\n", playerName, game->pacman.score, game->pacman.lives);

    // 显示游戏状态
    if (game->state == GAME_WIN) {
        printf("\nYou Win!\n");
    } else if (game->state == GAME_OVER) {
        printf("\nGame Over!\n");
    }
}

// 随机生成用户名
void randomName(char* name, int len) {
    const char* names[] = {"Alex", "Blake", "Casey", "Drew", "Evan", "Flynn", "Gale", "Harley", "Jules", "Kris", "Logan", "Morgan", "Parker", "Quinn", "Riley", "Skyler", "Taylor", "Val", "Wynn", "Zane"};
    int n = sizeof(names)/sizeof(names[0]);
    strncpy(name, names[rand() % n], len-1);
    name[len-1] = '\0';
}

int main() {
    // 设置控制台
    setup_console();

    // 打印技能树示例
    BinTreeNode* root = skilltreeInit();
    skilltreePrint(root);
    skilltreePrintStats(root);
    bintreeFree(root);

    srand(time(NULL));
    Game game;
    game_init(&game);
    int frame = 0;
    randomName(playerName, NAME_LEN);
    
    while (game.state == GAME_RUNNING) {
        // 处理Pacman移动
        Direction dir = handle_input();
        if (dir != -1) {
            pacman_move(&game.pacman, &game.map, dir);
        }
        // 幽灵每3帧才移动一次
        if (frame % 3 == 0) {
            for (int i = 0; i < GHOST_COUNT; i++) {
                ghost_move(&game.ghosts[i], &game.map, &game.pacman);
            }
        }
        // 检查碰撞和胜利条件
        for (int i = 0; i < GHOST_COUNT; i++) {
            if (ghost_collision(&game.ghosts[i], &game.pacman)) {
                game.pacman.lives--;
                if (!pacman_is_alive(&game.pacman)) {
                    game.state = GAME_OVER;
                }
            }
        }
        if (game.map.dotCount == 0) {
            game.state = GAME_WIN;
        }
        game_draw(&game);
        Sleep(100); // Windows睡眠函数，单位为毫秒
        frame++;
    }
    
    // 游戏结束，等待用户按键
    printf("\nPress any key to exit...\n");
    _getch();
    map_free_dots(&game.map);

    // === 集成排行榜，自动加入本局分数 ===
    Leaderboard lb;
    leaderboardInit(&lb);
    leaderboardAdd(&lb, playerName, game.pacman.score);
    leaderboardAdd(&lb, "Alice", 120);
    leaderboardAdd(&lb, "Bob", 200);
    leaderboardAdd(&lb, "Carol", 150);
    leaderboardSortByScore(&lb);
    printf("\n=== Leaderboard ===\n");
    leaderboardPrint(&lb);
    // ======================

    // === 打印技能树 ===
    BinTreeNode* skillroot = skilltreeInit();
    printf("\n=== Skill Tree ===\n");
    skilltreePrint(skillroot);
    skilltreePrintStats(skillroot);
    bintreeFree(skillroot);

    // 在游戏结束前清理资源
    cleanup_console();
    return 0;
} 